#include <pronano.h>
/*#include <DrvSYS.h>
#include <DrvUART.h>
#include <DrvGPIO.h>
#include <DrvFMC.h>
#include <DrvI2C.h>
#include <DrvPWM.h>
#include <DrvSPI.h>*/

volatile uint8_t bPrinter_status, bPrinter_error, bPrinter_warning;
void GPABCallback(uint32_t u32GpaStatus, uint32_t u32GpbStatus);
void GPCDECallback(uint32_t u32GpcStatus, uint32_t u32GpdStatus, uint32_t u32GpeStatus);
void EINT0Callback(void);
int  cur_sheet = 0, tail_sheet = -1, head_sheet = -1;
extern volatile uint16_t g_u16cnrData;
double Start_Dvalid_CNR1, Stop_Dvalid_CNR1, Start_Dvalid_CNR2, Stop_Dvalid_CNR2;

void Delay100ms(int a) {
  int i = 0;

  for (i = 0; i < (a*100); i++)
      SysTimerDelay(1000);
}

void Delay10ms(int a) {
  int i = 0;

  for (i = 0; i < (a*10); i++)
      SysTimerDelay(1000);
}

void SysTimerDelay(uint32_t us)
{
  SysTick->LOAD = us * 48; /* MCU core the 48MHz */
  SysTick->VAL = (0x00);
  SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1 << SYSTICK_ENABLE);

  /* Waiting for down-count to zero */
  while ((SysTick->CTRL &(1 << 16)) == 0);
}

void Init_console(void)
{
  STR_UART_T param;
  extern uint32_t SystemFrequency;
  UART_T * tUART;

  /* Unlock the locked registers before we can access them */
  UNLOCKREG(x);

  DrvGPIO_InitFunction(FUNC_GPIO);
  DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);
  /* Waiting for 12M Xtal stalble */
  SysTimerDelay(5000);
  //SYSCLK->PLLCON.FB_DV = 34;//62;
  SYSCLK->PLLCON.OE = 0x0;
  SYSCLK->PLLCON.PD= 0x0;	 
  //DrvSYS_SetPLLPowerDown(0);
  SYSCLK->PLLCON.BP = 0x0;
  /* HCLK clock source. 0: external 12MHz; 4:internal 22MHz RC oscillator */
  DrvSYS_SetHCLKSource(2);
  DrvSYS_SetClockDivider(E_SYS_HCLK_DIV, 0); /* HCLK clock frequency = HCLK
    clock source / (HCLK_N + 1) */

  //DrvGPIO_InitFunction(FUNC_UART0);
  param.u32BaudRate = 115200;
  param.u8cDataBits = DRVUART_DATABITS_8;
  param.u8cStopBits = DRVUART_STOPBITS_1;
  param.u8cParity = DRVUART_PARITY_NONE;
  param.u8cRxTriggerLevel = DRVUART_FIFO_4BYTES;
  param.u8TimeOut = 0;
  //DrvUART_Open(UART_PORT0, &param);

#ifdef ProNano_Fit_Mode  //fitting process
  DrvGPIO_InitFunction(FUNC_UART0);
  DrvUART_Open(DEBUG_INFO_PORT, &param);
#else
//UR2 is dummy port, we don't use it currently
  DrvGPIO_InitFunction(FUNC_UART2);
  DrvUART_Open(DEBUG_INFO_PORT, &param);
#endif

  //set HCLK to  50MHz
  //DrvSYS_SetPLLContent(DrvSYS_GetPLLContent(E_SYS_EXTERNAL_12M, 50000000));
  printf("PLL clock(Hz): %d, HCLK clock(Hz): %d\n", DrvSYS_GetPLLClockFreq(), DrvSYS_GetHCLKFreq());

// UR1 transfer TFT LCD command
  DrvGPIO_InitFunction(FUNC_UART1);
  param.u32BaudRate = 115200;
  param.u8cRxTriggerLevel = DRVUART_FIFO_1BYTES;
  DrvUART_Open(TFT_COMM_PORT, &param);
  //DrvUART_DisableInt(TFT_COMM_PORT_ID, DRVUART_RLSNT | DRVUART_THREINT | DRVUART_RDAINT);
  //DrvUART_EnableInt(TFT_COMM_PORT_ID, DRVUART_RLSNT | DRVUART_RDAINT, UART_INT_HANDLE);

#ifdef ProNano_Fit_Mode  //fitting process
#else

//UR0  used for thermal printer
  DrvGPIO_InitFunction(FUNC_UART0);
  param.u32BaudRate = 9600;
  //param.u32BaudRate = 115200;
  DrvUART_Open(PRINTER_PORT, &param);
  DrvUART_DisableInt(PRINTER_PORT,DRVUART_RLSINT | DRVUART_THREINT | DRVUART_RDAINT);
  DrvUART_EnableInt(PRINTER_PORT, DRVUART_RLSINT | DRVUART_RDAINT, UART_INT_HANDLE);

  tUART = (UART_T *)((uint32_t)UART0 + PRINTER_PORT_ID);  
  //tUART->MCR.RTS = u8Value;
  //tUART->MCR.LEV_RTS = 1;
  //DrvUART_SetRTS(PRINTER_PORT, 0, DRVUART_FIFO_1BYTES);
  //tUART->IER.AUTO_CTS_EN = 1;

//initialize the thermal printer
//reset printer, "ESC @"=="1B 40"
  buf2[0] = 0x1b; buf2[1] = 0x40;
  DrvUART_Write(PRINTER_PORT, buf2, 2);
#endif

//setting printer com port speed & printer black-level
#if 0
#ifdef PRINTER_PORT
  bPrinter_status = 0;
  bPrinter_error = 0;
  buf2[0] = 0x1E; buf2[1] = 0xEE; buf2[2] = 0x43;
  DrvUART_Write(PRINTER_PORT, buf2, 3);
  Delay100ms(5);
//  DrvUART_Read(PRINTER_PORT, buf2, 1);
//  bPrinter_status = buf2[0];
  if (bPrinter_status!=0x16) {
       printf("com port speed for printer phase1 issue error1\n");
  }
  else {
      bPrinter_status = 0;
      buf2[0] = 0xF8; buf2[1] = 0x81;
      DrvUART_Write(PRINTER_PORT, buf2, 2);
	  Delay100ms(5);
//      DrvUART_Read(PRINTER_PORT, buf2, 1);
//      bPrinter_status = buf2[0];
	  if (bPrinter_status!=0xAF) {
        printf("com port speed for printer phase1 issue error2\n");
	  }
	  else {
	      bPrinter_status = 0;
          buf2[0] = 0x05; buf2[1] = 0x06; buf2[2] = 0x1E; buf2[3] = 0xEE; buf2[4] = 0x85; buf2[5] = 0x0; buf2[6] = 0x0; buf2[7] = 0x0; buf2[8] = 0x0; buf2[9] = 0x0; buf2[10] = 0x0;
          DrvUART_Write(PRINTER_PORT, buf2, 11);
		  //while (bPrinter_status!=0x0F);
	      Delay100ms(5);
//          DrvUART_Read(PRINTER_PORT, buf2, 1);
//          bPrinter_status = buf2[0];
		  if (bPrinter_status==0x0F) {
	        printf("set com port speed for printer success!!!\n");

/*20130411 added by michael*/
//In fact, thermal printer still transfer in baud rate 9600, the seeting just affect the black level
		    /*DrvUART_Close(UART_PORT1);
		    param.u32BaudRate = 57600;
            DrvUART_Open(UART_PORT1, &param);
            DrvUART_DisableInt(UART_PORT1,DRVUART_RLSNT | DRVUART_THREINT | DRVUART_RDAINT);
            DrvUART_EnableInt(UART_PORT1, DRVUART_RLSNT | DRVUART_RDAINT, UART_INT_HANDLE);*/
		  }
	  }
  }
#endif
#endif

#if 1
  /* Initialize USB Device function */
  udcInit();

  /* Initialize mass storage device */
  udcFlashInit();
  _DRVUSB_ENABLE_MISC_INT(IEF_WAKEUP + IEF_FLD + IEF_USB + IEF_BUS);
  //EVF_FLD, EVF_BUS, EVF_SETUP, EVF_EPTF0, EVF_EPTF1, EVF_EPTF2, EVF_EPTF3, EVF_USB
  NVIC_SetPriority (USBD_IRQn, (1<<__NVIC_PRIO_BITS) - 2);
  NVIC_EnableIRQ(USBD_IRQn);
  LOCKREG();
#ifdef SYS_DEBUG
  printf("inital console & system clock: %dkHz\n", DrvSYS_GetHCLK());
#endif

#endif
}


void Init_Interface_IO(void)
{
  uint32_t u32HCLK, u32data, i, *pData;
  int32_t i32Err = 0;
  int32_t CC;
//  struct MaestroNano_Param_t param_data;
//  struct MD5Context md5c;
  unsigned char digest[17];

/*20130430 added by michael
configure ADC7/SS21/PA.7  mutiple function pin as ADC7*/
  DrvGPIO_Open(GPA, 7, IO_INPUT);
  DrvGPIO_InitFunction(E_FUNC_ADC7);
  outpw(&SYS->GPAMFP, inpw(&SYS->GPAMFP) | (0x1<<(7)));

  /*20130417 added by michael
  PB.3/nCTS switch back to PB.3*/
  //outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) & ~(0x1<<(3)));
  outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) | (0x3<<(2)));
  //outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) & ~(0x3<<(2)));

//power, enter_key, down_key, up_key
  DrvGPIO_Open(GPB, 9, IO_INPUT); //up_key
  DrvGPIO_InitFunction(E_FUNC_EXTINT0);
  outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) | (0x1<<(14)));
  //DrvGPIO_Open(GPB, 14, IO_INPUT);  //down_key
  DrvGPIO_Open(GPB, 13, IO_INPUT);  //enter_key
  DrvGPIO_Open(GPC, 0, IO_INPUT);  //inform MCU--->PC0
  DrvGPIO_Open(GPE, 5, IO_OUTPUT);  //output to Power control
  DrvGPIO_EnableInt(GPB, 9, IO_FALLING, MODE_EDGE);
  //DrvGPIO_EnableInt(GPB, 14, IO_FALLING, MODE_EDGE);
  DrvGPIO_EnableInt(GPB, 13, IO_FALLING, MODE_EDGE);
  DrvGPIO_EnableInt(GPC, 0, IO_RISING, MODE_EDGE);
  DrvGPIO_SetDebounceTime(1, DBCLKSRC_10K);
  DrvGPIO_EnableDebounce(GPB, 9);
  DrvGPIO_EnableDebounce(GPB, 14);
  DrvGPIO_EnableDebounce(GPB, 13);
  DrvGPIO_EnableDebounce(GPC, 0);
  DrvGPIO_SetIntCallback(GPABCallback, GPCDECallback);
  DrvGPIO_EnableEINT0(IO_FALLING, MODE_EDGE, EINT0Callback);
  //DrvGPIO_EnableEINT1(IO_FALLING, MODE_EDGE, EINT1Callback);
  outpw((uint32_t)&GPIOE->DOUT, inpw((uint32_t)&GPIOE->PIN) | (1 << 5));

//data flash init
  UNLOCKREG();
  DrvFMC_EnableISP();
  DrvFMC_Read(0x1FFF0, &u32data);
  if (u32data != VersionID) {  //first use data flash
	DrvFMC_Erase(METADATA_FLASH_BASE);
    //u32data = tail_sheet;
    DrvFMC_Write(0x1FFFC, tail_sheet);
	//u32data = head_sheet;
	DrvFMC_Write(0x1FFF8, head_sheet);
    //u32data = cur_sheet;
	DrvFMC_Write(0x1FFF4, cur_sheet);
	//u32data = VersionID;
	DrvFMC_Write(0x1FFF0, VersionID);
#ifdef FLASH_DEBUG
	DrvFMC_Read(0x1FFF0, &u32data);
    if (VersionID != u32data)
	  i32Err |= 1;
	DrvFMC_Read(0x1FFF4, &u32data);
	if (cur_sheet != u32data)
	  i32Err |= 1 << 1;
	DrvFMC_Read(0x1FFF8, &u32data);
	if (head_sheet != u32data)
	  i32Err |= 1 << 2;
	DrvFMC_Read(0x1FFFC, &u32data);
	if (tail_sheet != u32data)
	  i32Err |= 1 << 3;

	printf("Flash acess: default cur_sheet, tail_sheet, head_sheet ");
	if (!i32Err)
	  printf("[Ok]\n");
	else
	   printf("[Fail]\n");
#endif //macro FLASH_DEBUG
  }
  else {
     DrvFMC_Read(0x1FFF4, &u32data);
     cur_sheet = u32data;
	 DrvFMC_Read(0x1FFF8, &u32data);
	 head_sheet = u32data;
	 DrvFMC_Read(0x1FFFC, &u32data);
	 tail_sheet = u32data;
#ifdef FLASH_DEBUG
	 printf("cur_sheet=%d,  head_sheet=%d, tail_sheet=%d\n", cur_sheet, head_sheet, tail_sheet);
#endif //macro FLASH_DEBUG
  }
#ifdef 0
//load curve coefficient
  pData = (uint32_t *)&param_data;
  for (i = PARAM_FLASH_BASE; i < (PARAM_FLASH_BASE + sizeof(struct MaestroNano_Param_t)); i += 4, pData++) {
     DrvFMC_Read(i, &u32data);
     *pData = u32data;
  }
  
  MD5Init(&md5c);
  MD5Update (&md5c, (char *)&param_data, sizeof(struct MaestroNano_Param_t)-16);
  MD5Final (digest, &md5c);

#ifdef FLASH_DEBUG
  printf("param size: %d\n", sizeof(struct MaestroNano_Param_t));
  printf("calc md5 sum: ");
  for (i = 0; i < 16; i++)
     printf("%x", digest[i]);
  printf("\n");
  strncpy(digest, param_data.check_digits, 16);
  printf("expc md5 sum: ", digest);
  for (i = 0; i < 16; i++)
     printf("%x", digest[i]);
  printf("\n");
#endif
  if (!strncmp(param_data.check_digits, digest, 16)) {
#ifdef USE_FITTING_CURVE
      A260_curve = param_data.A260_curve;
	  A280_curve = param_data.A280_curve;
	  factor_230 = param_data.factor_230;
	  factor_260 = param_data.factor_260;
	  factor_280 = param_data.factor_280;
#else
	  for (i = 0; i < ((A260_LUT_Entries < A280_LUT_Entries) ?  A280_LUT_Entries:A260_LUT_Entries); i++) {
         if (i < A280_LUT_Entries) {
	       OD280[i] = param_data.OD280[i];
	       A280[i] = param_data.A280[i];
		 }
		 if (i < A260_LUT_Entries) {
	       OD260[i] = param_data.OD260[i];
	       A260[i] = param_data.A260[i];
		   A260_A280[i] = param_data.A260_A280[i];
		   A260_A230[i] = param_data.A260_A230[i];
		 }
		 //printf("param 1: %lf %lf %f %f %f %f\n", OD260[i], A260[i], OD280[i], A280[i], A260_A280[i], A260_A230[i]);
	  }
	  mPDCR = param_data.mPDCR;
#endif
#ifdef FLASH_DEBUG
	printf("load params success\n");
#endif
	//while (1);
  }
  else {
#ifdef USE_FITTING_CURVE
     factor_230 = factor_260 = factor_280 = 0;
#endif
  }
  LOCKREG();
#endif

  DrvGPIO_InitFunction(FUNC_I2C0);  //I2C for accessing external RTC
  UNLOCKREG();
  u32HCLK = DrvSYS_GetHCLK() * 1000;
  DrvI2C_Open(I2C_PORT0, 200000);
  /* Get I2C0 clock */
  u32data = DrvI2C_GetClockFreq(I2C_PORT0);
#ifdef SYS_DEBUG
  printf("I2C0 clock %d Hz\n", u32data);
#endif
  /* Enable I2C0 interrupt and set corresponding NVIC bit */
  DrvI2C_EnableInt(I2C_PORT0);
  DrvI2C_EnableTimeoutCount(I2C_PORT0, 0, 0);  //stop time-out
  //DrvI2C_InstallCallback(I2C_PORT0, TIMEOUT, I2C0_Timeout);
  LOCKREG();
#ifdef SYS_DEBUG
  printf("initial MCU GPIO ok\n");
#endif

/*20130515 added by michael
MBI5170 adjust Led drive current to control Led light intensity*/
  DrvGPIO_Open(GPA, Led_driver_SDI, IO_OUTPUT); //LED-driver_SDI  
  DrvGPIO_Open(GPA, Led_driver_MOD, IO_OUTPUT); //LED-driver_MOD
  DrvGPIO_Open(GPA, Led_driver_CLK, IO_OUTPUT); //LED-driver_CLK
  DrvGPIO_Open(GPA, Led_driver_OE, IO_OUTPUT); //LED-driver_OE, active low
  
  DrvGPIO_ClrBit(GPA, Led_driver_CLK);
  DrvGPIO_ClrBit(GPA, Led_driver_SDI);
  DrvGPIO_ClrBit(GPA, Led_driver_MOD);
  DrvGPIO_SetBit(GPA, Led_driver_OE);


/*20130516 added by michael
turn off LED 562, 595, 660nm*/
  DrvGPIO_Open(GPC, 6, IO_OUTPUT);
  DrvGPIO_Open(GPC, 15, IO_OUTPUT);
  DrvGPIO_Open(GPA, 0, IO_OUTPUT);
  LED562_OFF
  LED595_OFF
  LED660_OFF
  Led_Current_Sink_Off();

  //Led_Current_Sink_On(3);
  //for (i = 255; i >= 0; i -= 16) {
     //MBI5170_Set_Current(i);
	 //Delay100ms(10);
	 //Led_Current_Sink_Off();
  //}
#if 0
  LED562_ON
  MBI5170_Current_Adj_Mode();
  
  for (CC = 255, i = 0; i < 8; i++) {
	  if ((CC >> i) & 0x01) {
	  }
	  else {
	  }
  }
#endif
}


void PWM_setting_timer(S_DRVPWM_TIME_DATA_T sPt, uint8_t u8Timer, PFN_DRVPWM_CALLBACK pfncallback) {

  /* PWM Timer property */
  uint32_t status;
  /* Select PWM engine clock */
  DrvPWM_SelectClockSource(u8Timer&0xef, DRVPWM_HCLK);

  /* Set PWM Timer0 Configuration */
  status = DrvPWM_SetTimerClk(u8Timer, &sPt);
#ifdef SYS_DEBUG
  printf("PWM clock u32Frequency: %d\n", status);
#endif
  /* Enable Output for PWM Timer0 */
  DrvPWM_SetTimerIO(u8Timer&0xef, 1);

  /* Enable Interrupt Sources of PWM Timer0 and install call back function */
  DrvPWM_EnableInt(u8Timer&0xef, 0, pfncallback);
  /* Enable the PWM Timer 0 */	
}

void PWM_Init(void) {
  S_DRVPWM_TIME_DATA_T sPt;
  uint8_t u8Timer;
  double period = 0;

  DrvPWM_Open();
  /* Set PWM pins */
  //DrvGPIO_InitFunction(FUNC_PWM01);
  DrvGPIO_InitFunction(E_FUNC_PWM0);

//PWM0/PA.12 for DDC114.CONV
  sPt.u8Mode = DRVPWM_TOGGLE_MODE;
  sPt.u32Frequency = DDC114_CONV_Freq;
  sPt.u8HighPulseRatio = 50; /* High Pulse peroid : Total Pulse peroid = 1 : 100 */
  sPt.i32Inverter = 0;
  u8Timer = DRVPWM_TIMER0;
  PWM_setting_timer(sPt, u8Timer, NULL);

  /*Start_Dvalid_Xenon_PWM_CNR1 = 65217;
  Stop_Dvalid_Xenon_PWM_CNR1 = 65217 - 65217*(600)/62500;
  Start_Dvalid_Xenon_PWM_CNR2 = 65217 - 65217*(31250)/62500;
  Stop_Dvalid_Xenon_PWM_CNR2 = 65217 - 65217*(600+31250)/62500;*/

  period = (double)1/DDC114_CONV_Freq*1000000;
  printf("PWM CNR: %d, PWM period: %lf\n", g_u16cnrData, period);
  g_u16cnrData += 1;
/*20130415 added by michael
DDC114 CONV duty = (CMR+1), period=(CNR+1)
Data valid assert point fall in the CNR range (Start_Dvalid_CNR1, Stop_Dvalid_CNR1) or (Start_Dvalid_CNR2, Stop_Dvalid_CNR2)
*/
  Start_Dvalid_CNR1 = g_u16cnrData;
  Stop_Dvalid_CNR1 = g_u16cnrData - g_u16cnrData*(600)/period;
  Start_Dvalid_CNR2 = g_u16cnrData - g_u16cnrData*(period/2)/period;
  Stop_Dvalid_CNR2 = g_u16cnrData - g_u16cnrData*(600+period/2)/period;

  printf("data valid CNR: %lf, %lf, %lf, %lf\n", Start_Dvalid_CNR1, Stop_Dvalid_CNR1, Start_Dvalid_CNR2, Stop_Dvalid_CNR2);
}

void DDC114_Init(void) {
  //toggle output triggered by DDC114.DATA_VALID
#ifdef DDC114_DEBUG
  //DrvGPIO_Open(GPE, 6, IO_OUTPUT);
  DrvGPIO_Open(GPA, 11, IO_OUTPUT);
#endif

  // DDC114.DATA_VALID																										 	
  SYS->GPAMFP.PWM1_AD14 = 0;
  DrvGPIO_Open(GPA, 13, IO_INPUT);
  DrvGPIO_EnableInt(GPA, 13, IO_FALLING, MODE_EDGE);

/*20130416 added by michael
switch multi-function pin of SPI1:PC.8/SS10, PC.9/SPCLK, PC.10/MISO, PC.11/MOSI
only take PC.9/SPCLK <----> DDC114.DCLK
PC.10/MISO <-----> DDC114.DOUT
PC.8 switch to GPIO again tie to LOW
PC.11 not used
*/
  DrvGPIO_InitFunction(E_FUNC_SPI1);
  /* Configure SPI1 as a master, 32-bit transaction */
  // DDC114.DCLK, DDC114.DOUT
  DrvSPI_Open(eDRVSPI_PORT1, eDRVSPI_MASTER, eDRVSPI_TYPE1, 20);
  /* Enable the automatic slave select function of SS0. */
  DrvSPI_EnableAutoSS(eDRVSPI_PORT1, eDRVSPI_SS0);
  /* Set the active level of slave select. */
  DrvSPI_SetSlaveSelectActiveLevel(eDRVSPI_PORT1, eDRVSPI_ACTIVE_LOW_FALLING);
  /* Enable the automatic slave select function and set the specified slave select pin. */
  DrvSPI_EnableAutoSS(eDRVSPI_PORT1, eDRVSPI_SS0);
  /* SPI clock rate 3MHz */
  DrvSPI_SetClock(eDRVSPI_PORT1, SPI_Clock, 0);
  //DrvSPI_BurstTransfer(eDRVSPI_PORT0, 2, 2);	

// (1 << 8), DDC114.TEST='L'
/*20130521 added by michael
HW_V6:  PC.8  connect to TI sensor board DDC114.test directly
HW_V7:  PC.8 become unused and TI sensor board DDC114.test connect to ground directly
        HW_V7 is the first version for pro-nano evaluation
HW_V8:  PA.1 coonect to DDC114.test of MaestroNano but not to DDC114.test in ProNano
*/
  SYS->GPCMFP.SPI1_SS0 	=0;
  DrvGPIO_Open(GPC, 8, IO_OUTPUT);
  outpw((uint32_t) &GPIOC->DOUT, inpw((uint32_t) &GPIOC->PIN) & 0xfffffeff);
  DrvGPIO_Open(GPA, 1, IO_OUTPUT);
  DrvGPIO_ClrBit(GPA, 1);

  SYS->GPCMFP.SPI1_MOSI0 = 0;  //PC.11 switch back to GPIO again
}

void ProNano_Init(void) {
  /* Unlock the locked registers before we can access them */
  UNLOCKREG(x);

/* using divide frequency clock output, Ref. man pg.155-156 */
/* alternative ADC clock for TI-sensor board */
/*20130415 added by michael
CLKO = FRQDIV_CLK / 2^FSEL
*/
#ifdef CONFIG_DIV_Clkout
  SYS->GPBMFP.CPO0_CLKO = 1;
  SYS->ALTMFP.PB12_CLKO = 1;  /* pin mux */
  SYSCLK->FRQDIV.FDIV_EN = 1;
  SYSCLK->APBCLK.FDIV_EN = 1;
  SYSCLK->FRQDIV.FSEL = 2;  //FRQDIV_CLK divide by 2^FSEL
  SYSCLK->CLKSEL2.FRQDIV_S = 2;  //FRQDIV_CLK=HCLK
#endif
  

  PWM_Init();  //init the CONV PWM
  DDC114_Init();
  LOCKREG();
}
